package com.example.netty.sockettwo;

import com.example.netty.common.FieldClass;
import com.example.netty.pojo.*;
import com.example.netty.service.bak1.Bak1ServiceImpl;
import com.example.netty.service.bak1warning.Bak1ServiceWarningImpl;
import com.example.netty.service.bak2.Bak2ServiceImpl;
import com.example.netty.service.bak2warning.Bak2WarningServiceImpl;
import com.example.netty.service.communication.CommunicationServiceImpl;
import com.example.netty.service.gpspostitiondevice.GpsPostitionDeviceServiceImpl;
import com.example.netty.service.hyb.HybServiceImpl;
import com.example.netty.service.hybwarning.HybWarningServiceImpl;
import com.example.netty.service.hycyw.HycywServiceImpl;
import com.example.netty.service.hycywwarning.HycywWarningServiceImpl;
import com.example.netty.service.hymain.HyMainServiceImpl;
import com.example.netty.service.hymainwarning.HyMainWarningServiceImpl;
import com.example.netty.service.leftmain.LeftMainServiceImpl;
import com.example.netty.service.leftmainwarning.LeftMainWarningServiceImpl;
import com.example.netty.service.offside.OffsideServiceImpl;
import com.example.netty.service.power1.Power1ServiceImpl;
import com.example.netty.service.power1warning.Power1WarningServiceImpl;
import com.example.netty.service.power2.Power2ServiceImpl;
import com.example.netty.service.power2warning.Power2WarningServiceImpl;
import com.example.netty.service.power3.Power3ServiceImpl;
import com.example.netty.service.power3warning.Power3WarningServiceImpl;
import com.example.netty.service.powerbak.PowerBakServiceImpl;
import com.example.netty.service.powerbakwarning.PowerBakWarningServiceImpl;
import com.example.netty.service.rightmain.RightMainServiceImpl;
import com.example.netty.service.rightmainwarning.RightMainWarningServiceImpl;
import com.example.netty.service.shiplogdevice.ShiplogDeviceServiceImpl;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


@Component
public class NettyServerHandlerTwo extends ChannelInboundHandlerAdapter implements ApplicationContextAware {

    private static ApplicationContext context;

    private static final Logger log = LoggerFactory.getLogger(NettyServerHandlerTwo.class);

//    private static final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
//
//    private static ScheduledFuture<?> future=null;

//    // 创建一个定时任务
//    Runnable task = () -> {
//        try {
//            LeftMain leftMain = FieldClass.fieldVoluation(LeftMain.class);
//            LeftMainServiceImpl leftMainService = this.context.getBean(LeftMainServiceImpl.class);
//            leftMainService.add(leftMain);
//
////            RightMain rightMain = FieldClass.fieldVoluation(RightMain.class);
////            IRightMainService rightMainService = this.context.getBean(IRightMainService.class);
////            rightMainService.add(rightMain);
////
////            Power1 power1 = FieldClass.fieldVoluation(Power1.class);
////            IPower1Service power1Service = this.context.getBean(IPower1Service.class);
////            power1Service.add(power1);
////
////            Power2 power2 = FieldClass.fieldVoluation(Power2.class);
////            IPower2Service power2Service = this.context.getBean(IPower2Service.class);
////            power2Service.add(power2);
////
////            Power3 power3 = FieldClass.fieldVoluation(Power3.class);
////            IPower3Service power3Service = this.context.getBean(IPower3Service.class);
////            power3Service.add(power3);
////
////            PowerBak powerBak = FieldClass.fieldVoluation(PowerBak.class);
////            IPowerBakService powerBakService = this.context.getBean(IPowerBakService.class);
////            powerBakService.add(powerBak);
////
////            HyMain hyMain = FieldClass.fieldVoluation(HyMain.class);
////            IHyMainService hyMainService = this.context.getBean(IHyMainService.class);
////            hyMainService.add(hyMain);
////
////            Bak1 bak1 = FieldClass.fieldVoluation(Bak1.class);
////            IBak1Service bak1Service = this.context.getBean(IBak1Service.class);
////            bak1Service.add(bak1);
////
////            Bak2 bak2 = FieldClass.fieldVoluation(Bak2.class);
////            IBak2Service bak2Service = this.context.getBean(IBak2Service.class);
////            bak2Service.add(bak2);
////
////            Hycyw hycyw = FieldClass.fieldVoluation(Hycyw.class);
////            IHycywService hycywService = this.context.getBean(IHycywService.class);
////            hycywService.add(hycyw);
////
////            Hyb hyb = FieldClass.fieldVoluation(Hyb.class);
////            IHybService hybService = this.context.getBean(IHybService.class);
////            hybService.add(hyb);
//
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//    };



    /**
     * 客户端连接会触发
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("已建立通讯");
//        System.out.println(context.getEnvironment().getProperty("socket.second"));
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
//        if (evt instanceof IdleStateEvent) {//超时事件
//            IdleStateEvent idleEvent = (IdleStateEvent) evt;
//            if (idleEvent.state() == IdleState.READER_IDLE) {//读
//                log.info("超时事件");
//                ctx.channel().close();
//            }
//
//        }
//        super.userEventTriggered(ctx, evt);
    }


    /**
     * 客户端断开会触发
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("已断开通讯");
//        Communication communication=new Communication();
//        communication.setState(1);
//        LambdaQueryWrapper<Communication> lambdaQueryWrapper=new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.eq(Communication::getId,1);
//        lambdaQueryWrapper.eq(Communication::getState,0);
//        CommunicationMapper communicationMapper = this.context.getBean(CommunicationMapper.class);
//        communicationMapper.update(communication,lambdaQueryWrapper);
//        future = executorService.schedule(task, 30, TimeUnit.SECONDS);

    }

    /**
     * 客户端发消息会触发
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        Communication communication=new Communication();
//        communication.setState(0);
//        LambdaQueryWrapper<Communication> lambdaQueryWrapper=new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.eq(Communication::getId,1);
//        lambdaQueryWrapper.eq(Communication::getState,1);
//        CommunicationMapper communicationMapper = this.context.getBean(CommunicationMapper.class);
//        communicationMapper.update(communication,lambdaQueryWrapper);
//        if(future!=null && !future.isDone()){
//            log.info("任务状态: {}",future.isDone());
//            future.cancel(true);
//            log.info("杀死任务: {}",future.isDone());
//        }
        byte[] data = (byte[]) msg;
        String hexString = bytesToHexString(data);
        log.info("服务端收到消息Hex: {}", hexString);
        log.info("多少对Hex: {}", data.length);
        log.info("有多少个数:{}",(data.length-4)/2);
        String sub = hexString.substring(0, 4);
        log.info("截取前四位的字符: {}", sub);
        log.info("截取后四位的字符: {}", hexString.substring(hexString.length() - 4));
        log.info("转成十六进制的字符: {}", hexString.substring(4, hexString.length() - 4));
        String decimalString = hexToDecimal(hexString.substring(4, hexString.length() - 4));
        log.info("服务端Hex转成十进制: {}", decimalString);

        String[] strings = decimalString.split(" ");
        addAll(sub,strings,data,hexString,"ship_two");

        ctx.writeAndFlush(Unpooled.copiedBuffer(data));
    }


    public  void addAll(String sub,String [] strings,byte[] data,String hexString,String bucketName) throws Exception {
        List<Offside> OffsideList = new ArrayList<>();
        CommunicationServiceImpl communicationService = this.context.getBean(CommunicationServiceImpl.class);
        String second=context.getEnvironment().getProperty("socket.second");
        boolean isAdd=communicationService.last(bucketName,second);
        if(isAdd){
            communicationService.isAdd(bucketName);
        }
        if (sub.equals("FAF5") && data.length==516) {
            String[] s = Arrays.copyOfRange(strings, 0, 64);
            LeftMain leftMain = FieldClass.fieldVoluation(LeftMain.class, s, s.length);
            LeftMainServiceImpl leftMainService = this.context.getBean(LeftMainServiceImpl.class);
            leftMainService.add(bucketName,leftMain);
            LeftMainWarningServiceImpl leftMainWarningService = this.context.getBean(LeftMainWarningServiceImpl.class);
            LeftMainWarning leftMainWarning = leftMainWarningService.findOne(bucketName);
            boolean bool=Double.valueOf(s[0])>=200?true:false;
            FieldClass.fieldCompare(LeftMain.class, leftMain, leftMainWarning, OffsideList, "pid",bool);
//
            s = Arrays.copyOfRange(strings, 64, 128);
            RightMain rightMain = FieldClass.fieldVoluation(RightMain.class, s, s.length);
            RightMainServiceImpl rightMainService = this.context.getBean(RightMainServiceImpl.class);
            rightMainService.add(bucketName,rightMain);
            RightMainWarningServiceImpl rightMainWarningService = this.context.getBean(RightMainWarningServiceImpl.class);
            RightMainWarning rightMainWarning = rightMainWarningService.findOne(bucketName);
            bool=Double.valueOf(s[0])>=200?true:false;
            FieldClass.fieldCompare(RightMain.class, rightMain, rightMainWarning, OffsideList, "pid",bool);
//
            s = Arrays.copyOfRange(strings, 128, 144);
            Power1 power1 = FieldClass.fieldVoluation(Power1.class, s, s.length);
            Power1ServiceImpl power1Service = this.context.getBean(Power1ServiceImpl.class);
            power1Service.add(bucketName,power1);
            Power1WarningServiceImpl power1WarningService = this.context.getBean(Power1WarningServiceImpl.class);
            Power1Warning power1Warning = power1WarningService.findOne(bucketName);
            bool=Double.valueOf(s[0])>=200?true:false;
            FieldClass.fieldCompare(Power1.class, power1, power1Warning, OffsideList, "pid",bool);
//
            s = Arrays.copyOfRange(strings, 144, 160);
            Power2 power2 = FieldClass.fieldVoluation(Power2.class, s, s.length);
            Power2ServiceImpl power2Service = this.context.getBean(Power2ServiceImpl.class);
            power2Service.add(bucketName,power2);
            Power2WarningServiceImpl power2WarningService = this.context.getBean(Power2WarningServiceImpl.class);
            Power2Warning power2Warning = power2WarningService.findOne(bucketName);
            bool=Double.valueOf(s[0])>=200?true:false;
            FieldClass.fieldCompare(Power2.class, power2, power2Warning, OffsideList, "pid",bool);
//
            s = Arrays.copyOfRange(strings, 160, 176);
            Power3 power3 = FieldClass.fieldVoluation(Power3.class, s, s.length);
            Power3ServiceImpl power3Service = this.context.getBean(Power3ServiceImpl.class);
            power3Service.add(bucketName,power3);
            Power3WarningServiceImpl power3WarningService = this.context.getBean(Power3WarningServiceImpl.class);
            Power3Warning power3Warning = power3WarningService.findOne(bucketName);
            bool=Double.valueOf(s[0])>=200?true:false;
            FieldClass.fieldCompare(Power3.class, power3, power3Warning, OffsideList, "pid",bool);
//
            s = Arrays.copyOfRange(strings, 176, 192);
            PowerBak powerBak = FieldClass.fieldVoluation(PowerBak.class, s, s.length);
            PowerBakServiceImpl powerBakService = this.context.getBean(PowerBakServiceImpl.class);
            powerBakService.add(bucketName,powerBak);
            PowerBakWarningServiceImpl powerBakWarningService = this.context.getBean(PowerBakWarningServiceImpl.class);
            PowerBakWarning powerBakWarning = powerBakWarningService.findOne(bucketName);
            bool=Double.valueOf(s[0])>=200?true:false;
            FieldClass.fieldCompare(PowerBak.class, powerBak, powerBakWarning, OffsideList, "pid",bool);
//
            s = Arrays.copyOfRange(strings, 192, 208);
            HyMain hyMain = FieldClass.fieldVoluation(HyMain.class, s, s.length);
            HyMainServiceImpl hyMainService = this.context.getBean(HyMainServiceImpl.class);
            hyMainService.add(bucketName,hyMain);
            HyMainWarningServiceImpl hyMainWarningService = this.context.getBean(HyMainWarningServiceImpl.class);
            HyMainWarning hyMainWarning = hyMainWarningService.findOne(bucketName);
            FieldClass.fieldCompare(HyMain.class, hyMain, hyMainWarning, OffsideList, "pid",true);
//
            s = Arrays.copyOfRange(strings, 208, 224);
            Bak1 bak1 = FieldClass.fieldVoluation(Bak1.class, s, s.length);
            Bak1ServiceImpl bak1Service = this.context.getBean(Bak1ServiceImpl.class);
            bak1Service.add(bucketName,bak1);
            Bak1ServiceWarningImpl bak1WarningService = this.context.getBean(Bak1ServiceWarningImpl.class);
            Bak1Warning bak1Warning = bak1WarningService.findOne(bucketName);
            FieldClass.fieldCompare(Bak1.class, bak1, bak1Warning, OffsideList, "pid",true);

            s = Arrays.copyOfRange(strings, 224, 256);
            Bak2 bak2 = FieldClass.fieldVoluation(Bak2.class, s, s.length);
            Bak2ServiceImpl bak2Service = this.context.getBean(Bak2ServiceImpl.class);
            bak2Service.add(bucketName,bak2);
            Bak2WarningServiceImpl bak2WarningService = this.context.getBean(Bak2WarningServiceImpl.class);
            Bak2Warning bak2Warning = bak2WarningService.findOne(bucketName);
            FieldClass.fieldCompare(Bak2.class, bak2, bak2Warning, OffsideList, "pid",true);
//
            log.info("FAF5超标条数: {}", OffsideList.size());
            if (OffsideList.size()>0){
                OffsideServiceImpl iOffsideService=this.context.getBean(OffsideServiceImpl.class);
                iOffsideService.addBatch(bucketName,OffsideList);
            }
        } else if (sub.equals("FBF5") && data.length==516) {
            String ascii=hexStringToAscii(hexString.substring(644, 728));
            GpsPostitionDevice gpsPostitionDevice=new GpsPostitionDevice();
            gpsPostitionDevice.setZ1301(ascii.substring(0,6));
            gpsPostitionDevice.setZ1304(ascii.substring(6,16));
            gpsPostitionDevice.setZ1309(ascii.substring(16,28));
            gpsPostitionDevice.setZ1315(ascii.substring(28,40));
            gpsPostitionDevice.setZ1321(ascii.substring(40,42));
            FieldClass.fieldZero(gpsPostitionDevice);
            GpsPostitionDeviceServiceImpl gpsPostitionDeviceService=this.context.getBean(GpsPostitionDeviceServiceImpl.class);
            gpsPostitionDeviceService.add(bucketName,gpsPostitionDevice);

            ascii=hexStringToAscii(hexString.substring(772,796));
            ShiplogDevice shiplogDevice=new ShiplogDevice();
            shiplogDevice.setZ1401(ascii.substring(0,6));
            shiplogDevice.setZ1404(ascii.substring(6,12));
            FieldClass.fieldZero(shiplogDevice);
            ShiplogDeviceServiceImpl shiplogDeviceService=this.context.getBean(ShiplogDeviceServiceImpl.class);
            shiplogDeviceService.add(bucketName,shiplogDevice);

            String[] s = Arrays.copyOfRange(strings, 0, 80);
            Hycyw hycyw = FieldClass.fieldVoluation(Hycyw.class, s, s.length);
            HycywServiceImpl hycywService = this.context.getBean(HycywServiceImpl.class);
            hycywService.add(bucketName,hycyw);
            HycywWarningServiceImpl hycywWarningService = this.context.getBean(HycywWarningServiceImpl.class);
            HycywWarning hycywWarning=hycywWarningService.findOne(bucketName);
            FieldClass.fieldCompare(Hycyw.class, hycyw, hycywWarning, OffsideList,"pid",true);

            s = Arrays.copyOfRange(strings, 80, 128);
            Hyb hyb = FieldClass.fieldVoluation(Hyb.class, s, s.length);
            HybServiceImpl hybService = this.context.getBean(HybServiceImpl.class);
            hybService.add(bucketName,hyb);
            HybWarningServiceImpl hybWarningService = this.context.getBean(HybWarningServiceImpl.class);
            HybWarning hybWarning=hybWarningService.findOne(bucketName);
            FieldClass.fieldCompare(Hyb.class, hyb, hybWarning, OffsideList, "pid",true);
            log.info("FBF5超标条数: {}", OffsideList.size());
            if (OffsideList.size()>0){
                OffsideServiceImpl iOffsideService=this.context.getBean(OffsideServiceImpl.class);
                iOffsideService.addBatch(bucketName,OffsideList);
            }


        }
    }

    //解析hex字符串
    private String bytesToHexString(byte[] bytes) {
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) {
            hex.append(String.format("%02X", b));
        }
        return hex.toString();
    }

    //hex转成十进制
    private String hexToDecimal(String hex) {
        String[] hexValues = hex.split("(?<=\\G.{4})");
        StringBuilder decimal = new StringBuilder();

        for (String hexValue : hexValues) {
            if (!hexValue.isEmpty()) {
                int intValue = Integer.parseInt(hexValue, 16);
                decimal.append(intValue).append(" ");
            }
        }
        return decimal.toString();
    }

    //hex转成ascii
    private String hexStringToAscii(String hexString) {
        StringBuilder output = new StringBuilder();

        for (int i = 0; i < hexString.length(); i += 2) {
            String hexPair = hexString.substring(i, i + 2);
            int decimalValue = Integer.parseInt(hexPair, 16);
            char asciiChar = (char) decimalValue;
            output.append(asciiChar);
        }

        return output.toString();
    }




    /**
     * 数据读取完毕事件
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
//        log.info("服务端读取完毕: {}");
    }

    /**
     * 发生异常触发
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("程序异常");
        cause.printStackTrace();
        ctx.close();

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;

    }
}

